#import('dart:html');
#import('dart:json');

void main() {
  print("entered main");
  bool mouseDown = false;
  CanvasElement canvas = document.query('#bb');
  CanvasRenderingContext2D ctx = canvas.getContext("2d");
  String name;
  String color = "000";
  String icon = "";
  int width = 1;
  List<int> coords;
  List<int> iconCoord;
  int left_offset, top_offset;
  InputElement nameInput = document.query("#name");
  SelectElement _iconSelect = document.query("#icon");
  
  Future<ElementRect> f = canvas.rect;
  f.then((ElementRect rect) {
    left_offset = rect.offset.left;
    top_offset = rect.offset.top;
  });

  canvas.on.mouseDown.add( (MouseEvent e) {
    mouseDown = true;
    if (icon == "") {
      ctx.beginPath();
      coords = [];
      int x = e.clientX - left_offset;
      int y = e.clientY - top_offset;
      coords.add(x);
      coords.add(y);
      print("mouseDown = true x = ${x} y = ${y}");
      ctx.moveTo(x, y);
    } else {
      int x = e.clientX - left_offset;
      int y = e.clientY - top_offset;
      ImageElement image = new Element.tag('img');
      image.src = icon;
      image.on.load.add((event) {
        ctx.drawImage(image, x, y, 75, 75);
      });
      iconCoord = [];
      iconCoord.add(x);
      iconCoord.add(y);
      print("mouseDown = true icon = ${icon} src = ${image.src}");
    }
  });

  canvas.on.mouseMove.add( (MouseEvent e) {
    if (mouseDown && icon == "") {
      int x = e.clientX - left_offset;
      int y = e.clientY - top_offset;
      ctx.lineTo(x, y);
      coords.add(x);
      coords.add(y);
      ctx.stroke();
      print("stroke x = ${x} y = ${y}");
    }
  });

  WebSocket ws = new WebSocket("ws://" + window.location.host + "/bbws");

  canvas.on.mouseUp.add( (MouseEvent e) {
    if (mouseDown) {
      mouseDown = false;
      print("mouseDown = false");
      Map cmdMap = new Map();
      if (icon == null || icon.isEmpty()) {
        Map drawCmd = new Map();
        cmdMap["draw"] = drawCmd;
        drawCmd["color"] = color;
        drawCmd["width"] = width;
        drawCmd["coords"] = coords;
      } else {        
        Map iconCmd = new Map();
        cmdMap["drawIcon"] = iconCmd;
        iconCmd["icon"] = icon;
        iconCmd["iconCoord"] = iconCoord;
      }
      ws.send(JSON.stringify(cmdMap));
      coords = [];
      iconCoord = [];
    }
  });
  
   ws.on.message.add((event) {
      print("received data: ${event.data}");
      Map cmdMap = JSON.parse(event.data);
      cmdMap.forEach((k,v) {
        switch(k) {
          case "draw":
            if (v["coords"] != null) {
              String drawColor = v["color"];
              int drawWidth = v["width"];
              List<int> drawCoords = v["coords"];
              ctx.save();
              ctx.beginPath();
              for (int i=0; i < drawCoords.length; i += 2) {
                ctx.lineTo(drawCoords[i], drawCoords[i+1]);
              }
              ctx.setStrokeColor(drawColor);
              ctx.setLineWidth(drawWidth);
              ctx.stroke();
              ctx.restore();
            }
            break;
          case "setName":
            name = v;
            nameInput.value = v;
            break;
          case "setIcons":
            _iconSelect.elements.add(new OptionElement("none", "", false, false));
            Map iconMap = v;
            iconMap.forEach((n, p) {
              _iconSelect.elements.add(new OptionElement(n, p, false, false));
            });
            break;
          case "drawIcon":
            String remoteIcon = v["icon"]; 
            if (remoteIcon != "") {
              int x = v["iconCoord"][0];
              int y = v["iconCoord"][1];
              ImageElement image = new Element.tag('img');
              image.src = remoteIcon;
              image.on.load.add((event) {
                ctx.drawImage(image, x, y, 75, 75);
              });
            }
            icon = "";
            break;
          case "clear":
            ctx.save();
            
            // Use the identity matrix while clearing the canvas
            ctx.setTransform(1, 0, 0, 1, 0, 0);
            ctx.clearRect(0, 0, canvas.width, canvas.height);
             
            ctx.restore();
            break;
          default:
            print("Unkown Command: ${k}");
            break;
        }
      });
   });
   

   Map colorMap = { "Black" : "000", "Red" : "F00", "Green" : "0F0", "Blue" : "00F", "Yellow" : "FF0", "Cyan" : "0FF", "Magenta" : "F0F", "White" : "FFF" };
   SelectElement _colorSelect = document.query("#color");
   colorMap.forEach((c, v) {
     _colorSelect.elements.add(new OptionElement(c, v, false, false));
   });
   
   _colorSelect.on.change.add((event) {
     color = _colorSelect.options[_colorSelect.selectedIndex].value;
     ctx.setStrokeColor(color);
   });
   
   
   SelectElement _widthSelect = document.query("#width");
   ["1", "2", "3", "4", "5"].forEach((v) {
     _widthSelect.elements.add(new OptionElement(v, v, false, false));
   });
   
   _widthSelect.on.change.add((event) {
     width = Math.parseInt(_widthSelect.options[_widthSelect.selectedIndex].value);
     ctx.setLineWidth(width);
   });
   
   _iconSelect.on.change.add((event) {
     icon = _iconSelect.options[_iconSelect.selectedIndex].value;
   });
   
   ButtonElement _clearButton = document.query("#clear");
   _clearButton.on.click.add((event) {
     ctx.save();
      
     // Use the identity matrix while clearing the canvas
     ctx.setTransform(1, 0, 0, 1, 0, 0);
     ctx.clearRect(0, 0, canvas.width, canvas.height);
      
     ctx.restore();
     
     ws.send(JSON.stringify({"clear" : name}));

   });
}